`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/26 15:46:59
// Design Name: 
// Module Name: Get_gama_m_v2
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module Get_gama_m_v2#(
     parameter DATA_IN_WIDTH      = 24       , ////21bit frac
	 parameter DATA_OUT_WIDTH     = 32       ,
	 parameter COMPUTE_LEN_WIDTH  = 14    
	 
   )(
    input i_clk,
    input i_rstn,
    input signed [DATA_IN_WIDTH-1:0] i_real_norm_center,
    input i_real_norm_center_vld,
    input i_real_norm_center_last,
    output gama_m_vld,
    output  [DATA_OUT_WIDTH-1:0] gama_m    //24bit fra
//    output reg [COMPUTE_LEN_WIDTH-1:0] noweak_count,
//    output reg noweak_flag,
//    output o_real_norm_center,
//    output o_real_norm_valid,
//    output o_real_norm_last

    );

    
  /////////////////////// fft(a_cnorm);  
  wire  o_i_real_norm_center_ready;
  wire  [23:0]  o_fft_re,o_fft_im;
  wire  [79:0]  o_fft_data;
//  wire o_fft_data_vld_full;
  wire o_fft_data_vld;
  wire o_fft_data_last;
  
//  assign o_fft_re = o_fft_data[39:0];
//  assign o_fft_im = o_fft_data[79:40];
  
//  wire [9:0] o_fft_data_index;
  
  
  
//fft_amp fft_amp_inst (
//    .aclk(i_clk),                                                // input wire aclk
//    .aresetn(i_rstn),                                          // input wire aresetn
//    .s_axis_config_tdata({8'h01,3'd0,5'b01101}),                  // input wire [15 : 0] s_axis_config_tdata
//    .s_axis_config_tvalid(1'b1),                // input wire s_axis_config_tvalid
//    .s_axis_config_tready(),                // output wire s_axis_config_tready
//    .s_axis_data_tdata({24'b0,i_real_norm_center}),                      // input wire [31 : 0] s_axis_data_tdata
//    .s_axis_data_tvalid(i_real_norm_center_vld),                    // input wire s_axis_data_tvalid
//    .s_axis_data_tready(o_i_real_norm_center_ready),                    // output wire s_axis_data_tready
//    .s_axis_data_tlast(i_real_norm_center_last),                      // input wire s_axis_data_tlast
//    .m_axis_data_tdata(o_fft_data),                      // output wire [63 : 0] m_axis_data_tdata
//    .m_axis_data_tuser(o_fft_data_index),                      // output wire [15 : 0] m_axis_data_tuser
//    .m_axis_data_tvalid(o_fft_data_vld),                    // output wire m_axis_data_tvalid
//    .m_axis_data_tready(1'b1),                    // input wire m_axis_data_tready
//    .m_axis_data_tlast(o_fft_data_last),                      // output wire m_axis_data_tlast
//    .event_frame_started(),                  // output wire event_frame_started
//    .event_tlast_unexpected(),            // output wire event_tlast_unexpected
//    .event_tlast_missing(),                  // output wire event_tlast_missing
//    .event_status_channel_halt(),      // output wire event_status_channel_halt
//    .event_data_in_channel_halt(),    // output wire event_data_in_channel_halt
//    .event_data_out_channel_halt()  // output wire event_data_out_channel_halt
//  );
    reg refuse_data_ena;
     always @(posedge i_clk) begin
         if(~i_rstn) begin
             refuse_data_ena  <= 0;
         end
         else if(i_real_norm_center_last) begin
             refuse_data_ena <= 1'b1;
         end
  end 
diffft_8192_b2_v2 diffft_8192_b2_v2_inst (
    .clk(i_clk),                                             
    .rstn(i_rstn),                                                     
//    .din({24'b0,i_real_norm_center}),  
    .din({i_real_norm_center,24'b0}),                 
    .din_valid(i_real_norm_center_vld&~refuse_data_ena),                    
    .din_ready(o_i_real_norm_center_ready),                
    .din_last(i_real_norm_center_last),  
                
    .dout(o_fft_data),      //21bit fra                 
    .dout_valid(o_fft_data_vld),        
    .dout_last(o_fft_data_last),                
    .error()  
  );
    assign o_fft_re = o_fft_data[32:9];  //fra 12bit
    assign o_fft_im = o_fft_data[72:49];


  ////////////////////   
  wire [47:0] o_fft_re_square,o_fft_im_square;
  wire o_fft_im_square_valid,o_fft_re_square_valid;
  
      mult_myself #(
	     .N          (  24  ) ,
	     .M          (  24  )
	     ) 
    mult_myself3_inst (
      .clk(i_clk),                      // input wire clk
      .rstn(i_rstn),
      .data_rdy(o_fft_data_vld),      // 
      .mult1(o_fft_re),        //
      .mult2(o_fft_re),                  // 
      .res_rdy(o_fft_re_square_valid),            // 
      .res(o_fft_re_square)
    
    ); 
  
        mult_myself #(
	     .N          (  24  ) ,
	     .M          (  24  )
	     ) 
    mult_myself4_inst (
      .clk(i_clk),                      // input wire clk
      .rstn(i_rstn),
      .data_rdy(o_fft_data_vld),      // 
      .mult1(o_fft_im),        //
      .mult2(o_fft_im),                  // 
      .res_rdy(o_fft_im_square_valid),            // 
      .res(o_fft_im_square)  //28fra
    
    ); 
  
    wire [48:0] datamodule_square;
    wire datamodule_square_last;
  
  assign datamodule_square=o_fft_im_square+o_fft_re_square;
  
 
 
    xdelay_module #(
	     .D      (  24 ),
	     .W       (   1)
	      )
	    
   xdelay_module_last3_inst (
      .i_clk(i_clk),      // input wire clk
      .i_rstn(i_rstn),
      .s_i(o_fft_data_last),      
      .s_o(datamodule_square_last) 
    );   
//  cordic_myself #(
//	     .DIN_WIDTH      (  DATA_IN_WIDTH ) )
	    
//   cordic_myself2_inst (
//      .clk(i_clk),      // input wire clk
//      .rst_n(i_rstn),
//      .x(o_fft_re),      
//      .y(o_fft_im),  
//      .start(o_fft_data_vld),  
//      .angle(Phase_Data),  
//      .length(Real_Data),
//      .finished(Phase_Real_Data_valid)
//    );  
  
  
  
  
  
   
//  wire [79 : 0] m_axis_dout_tdata;
//  wire datamodule_valid;
//  wire datamodule_last;
//  wire [39:0] datamodule;
  
//cordic_module cordic_module_inst (
//    .aclk(i_clk),                                        // input wire aclk
//    .s_axis_cartesian_tvalid(o_fft_data_vld),  // input wire s_axis_cartesian_tvalid
//    .s_axis_cartesian_tlast(o_fft_data_last),    // input wire s_axis_cartesian_tlast
//    .s_axis_cartesian_tdata(o_fft_data),    // input wire [63 : 0] s_axis_cartesian_tdata
//    .m_axis_dout_tvalid(datamodule_valid),            // output wire m_axis_dout_tvalid
//    .m_axis_dout_tlast(datamodule_last),              // output wire m_axis_dout_tlast
//    .m_axis_dout_tdata(m_axis_dout_tdata)              // output wire [63 : 0] m_axis_dout_tdata
//  );
  
//  assign datamodule=m_axis_dout_tdata[39:0];
  
//  wire [79:0] datamodule_mult;
//  reg  datamodule_mult_valid_d1,datamodule_mult_valid_d2,datamodule_mult_valid_d3,datamodule_mult_valid_d4;
//  reg  datamodule_mult_last_d1,datamodule_mult_last_d2,datamodule_mult_last_d3,datamodule_mult_last_d4;
  
//  mult_module mult_module_inst (
//    .CLK(i_clk),  // input wire CLK
//    .A(datamodule),      // input wire [26 : 0] A
//    .B(datamodule),      // input wire [26 : 0] B
//    .P(datamodule_mult)      // output wire [53 : 0] P    42bit fra
//  );
  

  
  
//  always @(posedge i_clk) 
//      begin
//          if(!i_rstn)
//              begin
//                  datamodule_mult_valid_d1 <= 0    ;
//                  datamodule_mult_valid_d2 <= 0    ;
//                  datamodule_mult_valid_d3<=0;
//                  datamodule_mult_valid_d4<=0;
//                  datamodule_mult_last_d1<=0;
//                  datamodule_mult_last_d2<=0;
//                  datamodule_mult_last_d3<=0;
//                  datamodule_mult_last_d4<=0;               
//              end
//          else 
//              begin
//                  datamodule_mult_valid_d1 <= datamodule_valid       ;
//                  datamodule_mult_valid_d2 <= datamodule_mult_valid_d1 ;
//                  datamodule_mult_valid_d3<=datamodule_mult_valid_d2;
//                  datamodule_mult_valid_d4<=datamodule_mult_valid_d3;
//                  datamodule_mult_last_d1<=datamodule_last;
//                  datamodule_mult_last_d2<=datamodule_mult_last_d1;
//                  datamodule_mult_last_d3<=datamodule_mult_last_d2;
//                  datamodule_mult_last_d4<=datamodule_mult_last_d3;

//              end
//      end
  
  
  
  
          reg  [48:0] max_data;
          reg  max_data_rst;
          
          always @(posedge i_clk) begin
              if(max_data_rst||~i_rstn) max_data <= 0;
              else if(o_fft_im_square_valid) begin if(max_data>datamodule_square) max_data <= max_data;
              else max_data <=datamodule_square;
              end

              else max_data <= max_data;
          end
 wire   [35:0] o_gama_m ;     
assign   o_gama_m = max_data[48:13];
 assign   gama_m=  o_gama_m[35:4];  //20bit fra   
          reg state,next_state;
          reg max_data_vld;
          localparam Init=1'b0, Start=1'b1;
          always @(*) begin
              case(state)
                  Init: begin
                      if(~i_rstn) next_state = Init;
                      else next_state = Start;
                  end
                  Start: begin
                      if(~i_rstn) next_state = Init;
                      else next_state = Start;
                  end
              endcase
          end
          
          // State transfer block
          always @(posedge i_clk) begin
              if(~i_rstn) state <= Init;
              else state <= next_state;
          end
          
      
          // State output
          always @(posedge i_clk) begin
              // in default we disable and reset all counter
              max_data_rst     <= 1;
              max_data_vld     <= 0; // output data is invalid
              case(next_state)
                  Init: ; // do as the default
                  Start: begin
                      max_data_vld <= datamodule_square_last;
                      max_data_rst <= datamodule_square_last;
                      end
              endcase
          end
          
          assign gama_m_vld = max_data_vld;
      /*
          always@(posedge i_clk)begin
              if(~i_rstn) begin
                  
              end
              else begin
                  
              end
          end
       */   
      endmodule

  
  
  
  
  
  